package org.lex.notepad.ui;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.charset.Charset;

import javax.swing.JFileChooser;
import javax.swing.SwingWorker;


import org.lex.app.prefs.ResourceMap;
import org.lex.notepad.Notepad;
import org.lex.notepad.ui.filechooser.FileChooserFactory;
import org.lex.notepad.ui.filechooser.PreviewFileChooser;
import org.lex.notepad.util.CK;
import org.lex.notepad.util.CharsetUtils;
import org.lex.swing.Option;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class NotepadActions {
	public static final String DEFAULT_FILE_NAME = "Untitled";

	private Logger log = LoggerFactory.getLogger(NotepadActions.class);
	private Notepad app = null;
	private ResourceMap rm = null;
	File currentFile = null;

	public NotepadActions() {
		this.app = Notepad.getApplication();
		this.rm = app.getContext().getResourceManager().getResourceMap();
		// DnD support
		// new DropHandler( this );
	}

	public Option newFileAction() {
		return this.closeAction();
	}

	public void openFileAction() {
		Option close = this.closeAction();
		if (true == close.isYesOption()) {
			File dir = currentFile;
			if (null == dir) {
				String pwd = rm.getString(CK.WORKING_DIRECTORY);
				log.debug(CK.WORKING_DIRECTORY + "=" + pwd);
				if (null != pwd) {
					dir = new File(pwd);
				}
			}
			PreviewFileChooser fc = FileChooserFactory.getFileChooser(dir);
			int option = fc.showOpenDialog(app.getRootWindow());
			if (option == JFileChooser.APPROVE_OPTION) {
				File file = fc.getSelectedFile();
				log.debug("select file to open: " + file);
				if (null == file) {
					return;
				} else {
					this.openFile(file, fc.getCharset());
				}
			}
		}
	}

	public void openFile(final File file, final Charset charset) {
		if (null == file)
			return;
		this.currentFile = file;
		app.getRootWindow().setTitle(file.getName() + " - " + Notepad.DEFAULT_TITLE);
		new SwingWorker<Void, Void>() {
			protected Void doInBackground() throws Exception {
				app.getEditor().setCharset(charset);
				app.getEditor().read(new FileInputStream(file));
				app.getStatusBar().setCharset(charset);
				app.getStatusBar().setFileFormat(CharsetUtils.parseFileFormat(app.getEditor().getDocument()));
				return null;
			}
		}.execute();
	}

	public Option saveAction() {
		if (false == this.app.getEditor().hasContentChanged()) {
			// �ļ�������û�б��޸�
			return Option.YES;
		} else if (null == this.currentFile) {
			// ��һ���µ��ļ�����û���ļ�����Ҫ����SaveAs�������ļ�
			return this.saveAsAction();
		} else {
			// �ļ������ݱ��޸Ĺ����Ѿ�֪�����ļ���ֻ��Ҫ�򵥵ñ���Ϳ�����
			new SwingWorker<Void, Void>() {
				protected Void doInBackground() throws Exception {
					app.getEditor().write(new FileOutputStream(currentFile));
					return null;
				}
			}.execute();
			return Option.YES;
		}
	}

	public Option saveAsAction() {
		// build JFileChooser
		JFileChooser fc = new JFileChooser();
		fc.setMultiSelectionEnabled(false);
		fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
		fc.setFileHidingEnabled(false);
		if (null != currentFile)
			fc.setSelectedFile(currentFile);
		else
			fc.setCurrentDirectory(new File(rm.getString(CK.WORKING_DIRECTORY)));
		int opt = fc.showSaveDialog(app.getRootWindow());
		if (JFileChooser.APPROVE_OPTION == opt) {
			// save file
			this.currentFile = fc.getSelectedFile();
			app.getRootWindow().setTitle(currentFile.getName() + " - " + Notepad.DEFAULT_TITLE);
			new SwingWorker<Void, Void>() {
				@Override
				protected Void doInBackground() throws Exception {
					app.getEditor().write(new FileOutputStream(currentFile));
					return null;
				}
			}.execute();
			return Option.YES;
		}
		return Option.CANCEL;
	}

	/**
	 * Close current opened file.<br>
	 * 
	 * @return <ul>
	 *         <li>Option.YES: current opened file is closed.
	 *         <li>Option.NO: current opened file is not closed.
	 *         </ul>
	 */
	public Option closeAction() {
		if (false == this.app.getEditor().hasContentChanged()) {
			// editor's content not changed --> closed
			this.app.getEditor().clear();
			return Option.YES;
		} else {
			// editor's content has been changed --> prompt saving
			Option opt = UnsavedChangedDialog.showDialog(app.getRootWindow(), currentFile);
			if (opt.isYesOption()) {
				return this.saveAction();
			} else if (opt.isNoOption()) {
				this.app.getEditor().clear();
				return Option.YES;
			} else if (opt.isCancelOption()) {
				// do nothing
			}
			return opt;
		}
	}

	public boolean exitAction() {
		log.debug("try exit notepad program");
		Option opt = this.closeAction();
		if (true == opt.isYesOption()) {
			this.storeConfigurationToFile();
			return true;
		}
		return false;
	}

	public File getCurrentFile() {
		return currentFile;
	}

	public void setCurrentFile(File file) {
		this.currentFile = file;
	}

	private void storeConfigurationToFile() {
		// XMLConfig c = Config.instance();
		// if( null != currentFile )
		// c.setFile( CK.WORKING_DIRECTORY, currentFile );
		// // save main window
		// c.setProperty( CK.WINDOW_STATE, this.getState() );
		// c.setProperty( CK.WINDOW_EXTENDED_STATE, this.getExtendedState() );
		// c.setRectangle( CK.WINDOW_BOUNDS, this.getBounds() );
		// // save editor
		// NotepadEditor editor = this.getEditor();
		// c.setFont( CK.EDITOR_FONT, editor.getFont() );
		// c.setProperty( CK.EDITOR_WRAP_LINE, editor.getLineWrap() );
		// c.setProperty( CK.EDITOR_WRAP_WORD, editor.getWrapStyleWord() );
		// c.setProperty( CK.EDITOR_TAB_SIZE, String.valueOf(
		// editor.getTabSize() )
		// );
		// Config.storeConfigurationToFile();
	}
}
